package org.finesys.common.log.trace.util;

import io.opentracing.Span;
import io.opentracing.util.GlobalTracer;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.finesys.common.log.constants.TraceConstants;

import java.util.UUID;

@UtilityClass
public class TraceIdUtil {

    @Trace
    public static String traceId() {
        // skywalking traceId
        String swId = "";
        if (StringUtils.isNotBlank(TraceContext.traceId()) && !TraceConstants.SKYWALKING_NO_ID.equals(
                TraceContext.traceId())) {
            swId = TraceContext.traceId();
        }
        // skywalking traceId 优先级最高，其次jaeger，最次随机数
        if (StringUtils.isNotBlank(swId)) {
            return swId;
        }
        // jaeger traceId
        String jgId = "";
        Span activeSpan = GlobalTracer.get().activeSpan();
        if (null != activeSpan) {
            jgId = activeSpan.context().toTraceId();
        }
        if (StringUtils.isNotBlank(jgId)) {
            return jgId;
        }
        return generateTraceId();
    }

    @Trace
    public static String spanId() {
        // skywalking spanId
        int spanId = -1;
        if (TraceContext.spanId() != -1) {
            spanId = TraceContext.spanId();
        }
        // skywalking traceId 优先级最高，其次jaeger，最次随机数
        if (spanId != -1) {
            return spanId + "";
        }
        // jaeger spanId
        String jgId = "";
        Span activeSpan = GlobalTracer.get().activeSpan();
        if (null != activeSpan) {
            jgId = activeSpan.context().toSpanId();
        }
        if (StringUtils.isNotBlank(jgId)) {
            return jgId;
        }
        return "0";
    }

    @Trace
    public static String parentId() {
        // skywalking spanId
        int spanId = -1;
        if (TraceContext.spanId() != -1) {
            spanId = TraceContext.spanId();
        }
        // skywalking traceId 优先级最高，其次jaeger，最次随机数
        if (spanId != -1) {
            return spanId + "";
        }
        // jaeger spanId
        String jgId = "";
        Span activeSpan = GlobalTracer.get().activeSpan();
        if (null != activeSpan) {
            jgId = activeSpan.context().toSpanId();
        }
        if (StringUtils.isNotBlank(jgId)) {
            return jgId;
        }
        return "";
    }

    /**
     * 数字字符串方式加1
     */
    public String add(String value) {
        try {
            int val = Integer.parseInt(value);
            return (val + 1) + "";
        } catch (NumberFormatException e) {
            return "1";
        }
    }

    /**
     * 生成16位traceId
     */
    public String generateTraceId() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
    }
}
